import { pointsData } from "../assets/data/common";
import faceImg from "../assets/imgs/face.png";
import populationData from "../assets/data/population.json";
import temImg from "../assets/imgs/tem.png";

function getGradientColor() {
    const canvas = document.createElement('canvas')
    canvas.width = 1
    canvas.height = 255
    const ctx = canvas.getContext('2d')
    // 创建线性渐变色
    let linearGradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
    const colorStops = {
        0: "rgba(0,255,255,0.5)",
        0.2: "rgba(0,255,0,0.5)",
        0.4: "rgba(255,255,0,0.5)",
        1: "rgba(255,0,0,0.5)"
    }
    for (const key in colorStops) {
        linearGradient.addColorStop(key, colorStops[key]);
    }
    ctx.fillStyle = linearGradient;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    return canvas
}

function addPoints() {
    for (let i = 0; i < pointsData.length; i++) {
        const val = pointsData[i];
        //添加实体
        const entitie = viewer.entities.add({
            name: val.name,
            position: Cesium.Cartesian3.fromDegrees(val.x, val.y),
            point: {
                pixelSize : 10,
                color :Cesium.Color.YELLOW
            },
            properties: val
        });
    }
}

function addLabels() {
    for (let i = 0; i < pointsData.length; i++) {
        const val = pointsData[i];
        //添加实体
        const entity = viewer.entities.add({
            name: val.name,
            position: Cesium.Cartesian3.fromDegrees(val.x, val.y),
            label: {
                text: val.name,
                font: 'bold 19px 微软雅黑',
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                fillColor: Cesium.Color.RED,
                outlineColor: Cesium.Color.WHITE,
                outlineWidth: 3,
                verticalOrigin: Cesium.VerticalOrigin.CENTER,
                extrudedHeight: 1000
            },
            properties: val
        });
    }
}

function addBillboard() {
    for (let i = 0; i < pointsData.length; i++) {
        const val = pointsData[i];
        const entity = viewer.entities.add({
            id: 'entity' + val.id,
            name: val.name,
            position: Cesium.Cartesian3.fromDegrees(val.x, val.y),
            billboard: {
                image: faceImg,
                scale: 1, //原始大小的缩放比例
                horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                verticalOrigin: Cesium.VerticalOrigin.CENTER, // default: CENTER
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //CLAMP_TO_GROUND,
                rotation: Math.PI
            },
        });
    }
}

function addHeightPoints() {
    const data = populationData[0][1]
    const heightScale = 5000000
    const entities = viewer.entities
    for (let i = 0; i < data.length; i += 3) {
        const latitude = data[i];
        const longitude = data[i + 1];
        const height = data[i + 2];
        //Ignore lines of zero height.
        if (height === 0) {
            continue;
        }
        const color = Cesium.Color.fromHsl((0.6 - (height * 0.5)), 1.0, 0.5);
        //Create a random bright color.
        // var color = Cesium.Color.fromRandom();
        const surfacePosition = Cesium.Cartesian3.fromDegrees(longitude, latitude, 0);
        const heightPosition = Cesium.Cartesian3.fromDegrees(longitude, latitude, height * heightScale);
        //WebGL Globe only contains lines, so that's the only graphics we create.
        const polyline = new Cesium.PolylineGraphics();
        polyline.material = new Cesium.ColorMaterialProperty(color);
        polyline.width = new Cesium.ConstantProperty(4);
        polyline.arcType = new Cesium.ConstantProperty(Cesium.ArcType.NONE);
        polyline.positions = new Cesium.ConstantProperty([surfacePosition, heightPosition]);
        //The polyline instance itself needs to be on an entity.
        const entity = new Cesium.Entity({
            id: ' index_line_' + i.toString(),
            polyline: polyline
        });
        entities.add({
            id: ' index_point_' + i.toString(),
            position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
            point: {
                pixelSize : 2,
                color: color
            }
        })
        entities.add(entity);
    }
}

function addLines() {
    const redLine = viewer.entities.add({
        name: "Red line on terrain",
        polyline: {
            positions: Cesium.Cartesian3.fromDegreesArray([-75, 35, -125, 35]),
            width: 5,
            material: Cesium.Color.RED,
            clampToGround: true,
        },
    });

    const greenRhumbLine = viewer.entities.add({
        name: "Green rhumb line",
        polyline: {
            positions: Cesium.Cartesian3.fromDegreesArray([-75, 35, -125, 35]),
            width: 5,
            arcType: Cesium.ArcType.RHUMB,
            material: Cesium.Color.GREEN,
        },
    });

    const glowingLine = viewer.entities.add({
        name: "Glowing blue line on the surface",
        polyline: {
            positions: Cesium.Cartesian3.fromDegreesArray([-75, 37, -125, 37]),
            width: 10,
            material: new Cesium.PolylineGlowMaterialProperty({
                glowPower: 0.2,
                taperPower: 0.5,
                color: Cesium.Color.CORNFLOWERBLUE,
            }),
        },
    });

    const orangeOutlined = viewer.entities.add({
        name:
            "Orange line with black outline at height and following the surface",
        polyline: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([
                -75,
                39,
                250000,
                -125,
                39,
                250000,
            ]),
            width: 5,
            material: new Cesium.PolylineOutlineMaterialProperty({
                color: Cesium.Color.ORANGE,
                outlineWidth: 2,
                outlineColor: Cesium.Color.BLACK,
            }),
        },
    });

    const purpleArrow = viewer.entities.add({
        name: "Purple straight arrow at height",
        polyline: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([
                -75,
                43,
                500000,
                -125,
                43,
                500000,
            ]),
            width: 10,
            arcType: Cesium.ArcType.NONE,
            material: new Cesium.PolylineArrowMaterialProperty(
                Cesium.Color.PURPLE
            ),
        },
    });

    const dashedLine = viewer.entities.add({
        name: "Blue dashed line",
        polyline: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([
                -75,
                45,
                500000,
                -125,
                45,
                500000,
            ]),
            width: 4,
            material: new Cesium.PolylineDashMaterialProperty({
                color: Cesium.Color.CYAN,
            }),
        },
    });
}

function addPolygons() {
    var redPolygon = viewer.entities.add({
        name: "Red polygon on surface",
        polygon: {
            hierarchy: Cesium.Cartesian3.fromDegreesArray([
                -115.0,
                37.0,
                -115.0,
                32.0,
                -107.0,
                33.0,
                -102.0,
                31.0,
                -102.0,
                35.0,
            ]),
            material: Cesium.Color.RED,
        },
    });

    var greenPolygon = viewer.entities.add({
        name: "Green extruded polygon",
        polygon: {
            hierarchy: Cesium.Cartesian3.fromDegreesArray([
                -108.0,
                42.0,
                -100.0,
                42.0,
                -104.0,
                40.0,
            ]),
            extrudedHeight: 500000.0,
            material: Cesium.Color.GREEN,
            closeTop: false,
            closeBottom: false,
        },
    });

    var orangePolygon = viewer.entities.add({
        name: "Orange polygon with per-position heights and outline",
        polygon: {
            hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights([
                -108.0,
                25.0,
                100000,
                -100.0,
                25.0,
                100000,
                -100.0,
                30.0,
                100000,
                -108.0,
                30.0,
                300000,
            ]),
            extrudedHeight: 0,
            perPositionHeight: true,
            material: Cesium.Color.ORANGE.withAlpha(0.5),
            outline: true,
            outlineColor: Cesium.Color.BLACK,
        },
    });

    var bluePolygon = viewer.entities.add({
        name: "Blue polygon with holes",
        polygon: {
            hierarchy: {
                positions: Cesium.Cartesian3.fromDegreesArray([
                    -99.0,
                    30.0,
                    -85.0,
                    30.0,
                    -85.0,
                    40.0,
                    -99.0,
                    40.0,
                ]),
                holes: [
                    {
                        positions: Cesium.Cartesian3.fromDegreesArray([
                            -97.0,
                            31.0,
                            -97.0,
                            39.0,
                            -87.0,
                            39.0,
                            -87.0,
                            31.0,
                        ]),
                        holes: [
                            {
                                positions: Cesium.Cartesian3.fromDegreesArray([
                                    -95.0,
                                    33.0,
                                    -89.0,
                                    33.0,
                                    -89.0,
                                    37.0,
                                    -95.0,
                                    37.0,
                                ]),
                                holes: [
                                    {
                                        positions: Cesium.Cartesian3.fromDegreesArray([
                                            -93.0,
                                            34.0,
                                            -91.0,
                                            34.0,
                                            -91.0,
                                            36.0,
                                            -93.0,
                                            36.0,
                                        ]),
                                    },
                                ],
                            },
                        ],
                    },
                ],
            },
            material: Cesium.Color.BLUE.withAlpha(0.5),
            height: 0,
            outline: true, // height is required for outline to display
        },
    });

    var cyanPolygon = viewer.entities.add({
        name: "Cyan vertical polygon with per-position heights and outline",
        polygon: {
            hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights([
                -90.0,
                41.0,
                0.0,
                -85.0,
                41.0,
                500000.0,
                -80.0,
                41.0,
                0.0,
            ]),
            perPositionHeight: true,
            material: Cesium.Color.CYAN.withAlpha(0.5),
            outline: true,
            outlineColor: Cesium.Color.BLACK,
        },
    });

    var purplePolygonUsingRhumbLines = viewer.entities.add({
        name: "Purple polygon using rhumb lines with outline",
        polygon: {
            hierarchy: Cesium.Cartesian3.fromDegreesArray([
                -120.0,
                45.0,
                -80.0,
                45.0,
                -80.0,
                55.0,
                -120.0,
                55.0,
            ]),
            extrudedHeight: 50000,
            material: Cesium.Color.PURPLE,
            outline: true,
            outlineColor: Cesium.Color.MAGENTA,
            arcType: Cesium.ArcType.RHUMB,
        },
    });
}

function addBox() {
    viewer.entities.add({
        name : 'Red box with black outline',
        position: Cesium.Cartesian3.fromDegrees(106.591202, 26.841079, 5000.0),
        box : {
            dimensions : new Cesium.Cartesian3(3000.0, 4000.0, 5000.0),
            material : Cesium.Color.RED.withAlpha(0.5),
            outline : true,
            outlineColor : Cesium.Color.BLACK
        }
    });
}

function addCorridors() {
    var redCorridor = viewer.entities.add({
        name: "Red corridor on surface with rounded corners",
        corridor: {
            positions: Cesium.Cartesian3.fromDegreesArray([
                -100.0,
                40.0,
                -105.0,
                40.0,
                -105.0,
                35.0,
            ]),
            width: 200000.0,
            material: Cesium.Color.RED.withAlpha(0.5),
        },
    });
    var greenCorridor = viewer.entities.add({
        name: "Green corridor at height with mitered corners and outline",
        corridor: {
            positions: Cesium.Cartesian3.fromDegreesArray([
                -90.0,
                40.0,
                -95.0,
                40.0,
                -95.0,
                35.0,
            ]),
            height: 100000.0,
            width: 200000.0,
            cornerType: Cesium.CornerType.MITERED,
            material: Cesium.Color.GREEN,
            outline: true, // height required for outlines to display
        },
    });
    var blueCorridor = viewer.entities.add({
        name: "Blue extruded corridor with beveled corners and outline",
        corridor: {
            positions: Cesium.Cartesian3.fromDegreesArray([
                -80.0,
                40.0,
                -85.0,
                40.0,
                -85.0,
                35.0,
            ]),
            height: 0.0,
            extrudedHeight: 100000.0,
            width: 200000.0,
            cornerType: Cesium.CornerType.BEVELED,
            material: Cesium.Color.BLUE.withAlpha(0.5),
            outline: true, // height or extrudedHeight must be set for outlines to display
            outlineColor: Cesium.Color.WHITE,
        },
    });
}

function addEllipses() {
    var greenCircle = viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(-111.0, 40.0, 150000.0),
        name: "Green circle at height with outline",
        ellipse: {
            semiMinorAxis: 300000.0,
            semiMajorAxis: 300000.0,
            height: 200000.0,
            material: Cesium.Color.GREEN,
            outline: true, // height must be set for outline to display
        },
    });

    var redEllipse = viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(-103.0, 40.0),
        name: "Red ellipse on surface",
        ellipse: {
            semiMinorAxis: 250000.0,
            semiMajorAxis: 400000.0,
            material: Cesium.Color.RED.withAlpha(0.5),
        },
    });

    var blueEllipse = viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 100000.0),
        name: "Blue translucent, rotated, and extruded ellipse with outline",
        ellipse: {
            semiMinorAxis: 150000.0,
            semiMajorAxis: 300000.0,
            extrudedHeight: 200000.0,
            rotation: Cesium.Math.toRadians(45),
            material: Cesium.Color.BLUE.withAlpha(0.5),
            outline: true,
        },
    });
}

function addEllipsoid() {
    var blueEllipsoid = viewer.entities.add({
        name: "Blue ellipsoid",
        position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
        ellipsoid: {
            radii: new Cesium.Cartesian3(200000.0, 200000.0, 300000.0),
            material: Cesium.Color.BLUE,
        },
    });

    var redSphere = viewer.entities.add({
        name: "Red sphere with black outline",
        position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0),
        ellipsoid: {
            radii: new Cesium.Cartesian3(300000.0, 300000.0, 300000.0),
            material: Cesium.Color.RED.withAlpha(0.5),
            outline: true,
            outlineColor: Cesium.Color.BLACK,
        },
    });

    var outlineOnly = viewer.entities.add({
        name: "Yellow ellipsoid outline",
        position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0),
        ellipsoid: {
            radii: new Cesium.Cartesian3(200000.0, 200000.0, 300000.0),
            fill: false,
            outline: true,
            outlineColor: Cesium.Color.YELLOW,
            slicePartitions: 24,
            stackPartitions: 36,
        },
    });
}

function addPlanes() {
    var bluePlane = viewer.entities.add({
        name: "Blue plane",
        position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
        plane: {
            plane: new Cesium.Plane(Cesium.Cartesian3.UNIT_X, 0.0),
            dimensions: new Cesium.Cartesian2(400000.0, 300000.0),
            material: Cesium.Color.BLUE,
        },
    });

    var redPlane = viewer.entities.add({
        name: "Red plane with black outline",
        position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0),
        plane: {
            plane: new Cesium.Plane(Cesium.Cartesian3.UNIT_Y, 0.0),
            dimensions: new Cesium.Cartesian2(400000.0, 300000.0),
            material: Cesium.Color.RED.withAlpha(0.5),
            outline: true,
            outlineColor: Cesium.Color.BLACK,
        },
    });

    var outlineOnly = viewer.entities.add({
        name: "Yellow plane outline",
        position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0),
        plane: {
            plane: new Cesium.Plane(Cesium.Cartesian3.UNIT_Z, 0.0),
            dimensions: new Cesium.Cartesian2(400000.0, 300000.0),
            fill: false,
            outline: true,
            outlineColor: Cesium.Color.YELLOW,
        },
    });
}

function addWalls() {
    var redWall = viewer.entities.add({
        name: "Red wall at height",
        wall: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([
                -115.0,
                44.0,
                200000.0,
                -90.0,
                44.0,
                200000.0,
            ]),
            minimumHeights: [100000.0, 100000.0],
            material: Cesium.Color.RED,
        },
    });

    var greenWall = viewer.entities.add({
        name: "Green wall from surface with outline",
        wall: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([
                -107.0,
                43.0,
                100000.0,
                -97.0,
                43.0,
                100000.0,
                -97.0,
                40.0,
                100000.0,
                -107.0,
                40.0,
                100000.0,
                -107.0,
                43.0,
                100000.0,
            ]),
            material: new Cesium.ImageMaterialProperty({
                image: '/css/imgs/wall.png',
                transparent: false,
                repeat: new Cesium.Cartesian2(50.0, 25.0)
            }),
            outline: false
        },
    });

    var blueWall = viewer.entities.add({
        name: "Blue wall with sawtooth heights and outline",
        wall: {
            positions: Cesium.Cartesian3.fromDegreesArray([
                -115.0,
                50.0,
                -112.5,
                50.0,
                -110.0,
                50.0,
                -107.5,
                50.0,
                -105.0,
                50.0,
                -102.5,
                50.0,
                -100.0,
                50.0,
                -97.5,
                50.0,
                -95.0,
                50.0,
                -92.5,
                50.0,
                -90.0,
                50.0,
            ]),
            maximumHeights: [
                100000,
                200000,
                100000,
                200000,
                100000,
                200000,
                100000,
                200000,
                100000,
                200000,
                100000,
            ],
            minimumHeights: [
                0,
                100000,
                0,
                100000,
                0,
                100000,
                0,
                100000,
                0,
                100000,
                0,
            ],
            material: Cesium.Color.BLUE.withAlpha(0.5),
            outline: false,
            outlineColor: Cesium.Color.BLACK
        },
    });
    blueWall.wall.material = new Cesium.ImageMaterialProperty({
        image: getGradientColor(),
        transparent: true
    })
}

function addModels() {
    viewer.entities.add({
        name: '/model/car.glb',
        position:  Cesium.Cartesian3.fromDegrees(
            106.591202, 26.841079,
            0
        ),
        model: {
            uri: '/model/car.glb',
            minimumPixelSize: 128,
            maximumScale: 20000,
        },
    });

    viewer.entities.add({
        name: '/model/airplane.glb',
        position:  Cesium.Cartesian3.fromDegrees(
            106.442389, 26.841079,
            1000000
        ),
        model: {
            uri: '/model/airplane.glb',
            minimumPixelSize: 128,
            maximumScale: 20000,
        },
    });
}

function addRectangle() {
    const [west, south, east, north] = [113.207, 37.4351, 119.427, 42.7022]
    viewer.entities.add({
        rectangle: {
            coordinates: Cesium.Rectangle.fromDegrees(west, south, east, north),
            material: Cesium.Color.RED,
            height: 0
        }
    });
}

function addImage() {
    const [west, south, east, north] = [113.207, 37.4351, 119.427, 42.7022]
    viewer.entities.add({
        rectangle: {
            coordinates: Cesium.Rectangle.fromDegrees(west, south, east, north),
            material: new Cesium.ImageMaterialProperty({
                image: temImg,
                transparent: true
            }),
            height: 0
        }
    });
}

export {
    addPoints,
    addLabels,
    addBillboard,
    addHeightPoints,
    addLines,
    addPolygons,
    addBox,
    addCorridors,
    addEllipses,
    addEllipsoid,
    addPlanes,
    addWalls,
    addModels,
    addRectangle,
    addImage
}